home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / mcomm540.zip / ASYNC.DOC < prev    next >
Text File  |  1991-01-10  |  92KB  |  2,453 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.             ASYNCHRONOUS FUNCTIONS FOR MICROSOFT, TURBO, OR ZORTECH C
  9.  
  10.  
  11.             The LIB(s) on the included disk are libraries of serial
  12.          communications functions designed specifically for use with
  13.          Microsoft C, Turbo C / C++, and Zortech C / C++.  The regis-
  14.          tered version has LIBs for all memory models.  The shareware
  15.          version is small model only.
  16.  
  17.  
  18.                     --- Features of the library functions ---
  19.  
  20.             o Support for 16550 UART's FIFO mode of operation
  21.  
  22.             o Fully interrupt driven
  23.  
  24.             o Baud rates up to 115,200 baud
  25.  
  26.             o User defined transmit and receive ring buffer sizes.
  27.  
  28.             o Ring buffers may be in placed in FAR memory even in small
  29.               and medium model programs.
  30.  
  31.             o User defined port addresses, IRQ use, and interrupt vector
  32.               numbers.
  33.  
  34.             o Support for simultaneous operation of 2 ports.
  35.  
  36.             o Built in support for XON/XOFF and hardware flow control
  37.  
  38.             o Block transmit and receive functions
  39.  
  40.             o Receive buffer look ahead function
  41.  
  42.             o 100% assembler code for maximum speed
  43.  
  44.             o Totally compatible with Microsoft C, Turbo C, Zortech C,
  45.               and other C compilers that use standard Microsoft high
  46.               level language calling conventions.
  47.  
  48.  
  49.  
  50.          ---------------------------------------------------------------
  51.                 Mike Dumdei,  6 Holly Lane,  Texarkana TX  75503
  52.                 MCOMM5 (c) 1989, 1990, 1991  All Rights Reserved
  53.          ---------------------------------------------------------------
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.                       REGISTRATION AND DISTRIBUTION POLICY
  61.  
  62.             MCOMM5, the various versions of Smalterm, the ANSI video
  63.          routines, and other miscellaneous functions contained in the
  64.          COMM_x libraries are distributed as shareware.  If you use
  65.          these functions regularly please register them.
  66.  
  67.             Two types of registration are available for MCOMM5.  The
  68.          first is $25 and includes assembled libraries for all memory
  69.          models.  The $25 registration does not include source code.
  70.          The second type of registration is $45 and includes libraries
  71.          and source code.  Previous versions were $25 for source code
  72.          and libraries.  If you send $25 and want source code based on
  73.          previous offers, you will receive a previous version of the
  74.          source.  Registered users of versions prior to version 5 may
  75.          upgrade their libraries for $3 or upgrade source code version
  76.          for $10.
  77.  
  78.             I also have developed a version of these routines for use
  79.          with the DigiBoard(r) COM4 and COM8 boards that support up to
  80.          32 DigiBoard ports and 1 standard port simultaneously.  Please
  81.          contact me if you are interested in this product.  It is $35
  82.          for libraries only.  No source is available for the DigiBoard
  83.          version.
  84.  
  85.             Considerable time and effort has gone into developing and
  86.          debugging these routines.  If you are not a registered user and
  87.          have obtained a copy of the registered version, please take
  88.          time now to register the software or delete it.  The copy you
  89.          have is a registered version if it contains libraries for any
  90.          memory model other than small model or if any of the ASM source
  91.          code is included.
  92.  
  93.             This software is provided as is without warranty as to its
  94.          fitness for a particular use or being free of errors.  I assume
  95.          no liability for any loss or damages you may incur through its
  96.          use.  I will, however, make every effort to correct any
  97.          software errors that may exist, and provide you with a working
  98.          version.
  99.  
  100.             I will continue to assist registered and non-registered
  101.          users whenever possible.  If you have any problems using these
  102.          routines or questions, I may be contacted at:
  103.  
  104.             Split Up the Middle BBS   --  903 838-6713 (modem)
  105.             Mike Dumdei               --  903 838-8307 (voice)
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.                                  GETTING STARTED
  113.  
  114.          All functions included in this library are listed on the fol-
  115.          lowing pages in alphabetical order.  The basic functions needed
  116.          to begin are: async_open, async_tx, async_rx, and async_close.
  117.  
  118.          Functions are also available to support XON/XOFF and hardware
  119.          flow control, the 16550 UART, block transmit and receive,
  120.          receive buffer look ahead, and several other features.
  121.  
  122.          All functions take a pointer to an ASYNC structure for one of
  123.          its arguments.  This structure is defined in COMM.H.  It
  124.          may be helpful to think of this structure as being similar to
  125.          the standard C library 'FILE *'.
  126.  
  127.          If you have been using versions of these routines prior to
  128.          version 5.00, there have been some changes made that will
  129.           require you to make some modifications to any existing code
  130.          before it can be used with the new libraries.  The main
  131.          differences are:
  132.  
  133.             > Async_open takes different parameters.  Also, instead
  134.               of the open function automatically allocating the ring
  135.               buffers for you, you provide the ring buffers.
  136.  
  137.             > All functions now take a pointer to an ASYNC structure
  138.               as the first argument rather than 0 (COM1) or 1 (COM2).
  139.  
  140.             > LITES is no longer supported.
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147.                             NOTES ON 16550 FIFO MODE
  148.  
  149.             The 16550 UART is automatically detected and enabled when
  150.          async_open is called.  If, for some reason, you want to operate
  151.          a 16550 UART in non-FIFO mode, automatic detection and use can
  152.          be disabled.  See async_open for more information.
  153.  
  154.  
  155.                           --- Use of receiver FIFOs ---
  156.  
  157.             The receiver trigger level may be programmed for 1, 4, 8, or
  158.          14 bytes by the async_FIFOrxlvl function.  When a port is first
  159.          opened the trigger is set to 1 byte.  There are 3 reasons why I
  160.          chose to default to a 1 byte receive trigger level.
  161.  
  162.             1) While a higher trigger level results in less CPU
  163.                overhead, it also provides less overrun protection if the
  164.                CPU is slow to respond.  For example, with a 1 byte
  165.                trigger level the 16550 -- when it generates an interrupt
  166.                -- can hold 15 more characters in its FIFOs before the
  167.                CPU responds.  With a 14 byte trigger level it will only
  168.                have room for 2 more characters.
  169.  
  170.             2) The MCOMM interrupt functions completely empty the
  171.                receiver FIFOs every time an interrupt occurs.  If the
  172.                CPU is slow to respond, the interrupt handler will
  173.                process 2,3,4.. characters (whatever is in the FIFOs)
  174.                whenever it does get control so the data still gets
  175.                buffered if the CPU isn't able to keep up.
  176.  
  177.             3) Setting the trigger level at higher trigger levels when
  178.                displaying incoming data to the screen will result in a
  179.                jerky looking display, especially at low baud rates.
  180.                Again, this is because MCOMM empties the buffer
  181.                completely when it processes the interrupt.  With a
  182.                trigger level other than 1, data stacks up in the FIFOs
  183.                until the trigger level is reached.  When the interrupt
  184.                finally occurs, all the data in the FIFOs is pulled out
  185.                and made available to the higher level functions at
  186.                one time.  The result is your code sits for 4, 8, or 14
  187.                bytes (whatever the trigger is) and then puts those bytes
  188.                on the screen in a burst.  It looks rough at low baud
  189.                rates.  At 9600 baud and above you could probably get by
  190.                with a slightly higher trigger level.
  191.  
  192.             For best use of the receive FIFOs, stick with 1 byte trigger
  193.          level when displaying data to the screen.  If your application
  194.          does not display the data or uses a high baud rate, you may
  195.          want to experiment with setting it to either 4 or 8 bytes.
  196.  
  197.  
  198.                           --- Use of transmit FIFOs ---
  199.  
  200.             The MCOMM transmit interrupt handler takes a parameter (set
  201.          by async_FIFOtxlvl) that is the maximum number of bytes to load
  202.          into the transmit FIFOs at one time.  The default value for
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.                             NOTES ON 16550 FIFO MODE
  210.  
  211.          this parameter is 3 bytes.  The reason for not loading up the
  212.          FIFOs to maximum capacity (16 bytes) is flow control.  The
  213.          16550 UART will continue to transmit characters in its FIFOs
  214.          regardless of the state of CTS, DSR, or CD, or if an XOFF is
  215.          received.  It is totally up to the software to respond to
  216.          requests for flow control.  If the FIFOs are loaded with more
  217.          bytes than the receiver can handle when it invokes flow
  218.          control, the receiver gets overwritten.  There is a bit that
  219.          can be sent to the UART to flush the transmit FIFOs but then it
  220.          is impossible to tell what was flushed and what was sent.  The
  221.          solution is to not the load the FIFOs up so full.  If the
  222.          receiving device can handle more than 3 characters of overrun,
  223.          use a larger value.  If the application does not require flow
  224.          control, you can use a 16 byte level with no problems.
  225.  
  226.             Another factor to consider concerning the transmit FIFO byte
  227.          level is that (from the NS Data Communications/LAN/UART
  228.          Handbook) the transmit FIFO empty indication will be delayed by
  229.          1 character time minus the last stop bit until there are at
  230.          least 2 bytes in the transmit FIFOs simultaneously for the
  231.          current transmit operation.  After the 2 byte requirement is
  232.          met the transmit interrupt occurs immediately when the transmit
  233.          FIFOs empty.  Using a value of 3 or above (1 byte for the
  234.          transmit shift register and 2 for the FIFO registers)
  235.          guarantees the interrupt delay is deactivated.  Once the '2
  236.          bytes in the FIFOs' requirement is met, the transmit byte level
  237.          can be reduced if necessary.
  238.  
  239.  
  240.                   --- Problems with Western Digital 16550s ---
  241.  
  242.          The following problems DO NOT apply to the National Semicon-
  243.          ductor version of the 16550.  Neither are they unique to MCOMM.
  244.  
  245.          Western Digital 16550 UARTs have two problems you should be
  246.          aware of if your application will be ran on system that uses
  247.          this chip.
  248.  
  249.          The first of these only shows up under the following
  250.          conditions:
  251.  
  252.             1) The UART is in FIFO mode.
  253.             2) A low baud rate is being used.
  254.             3) The transmitter is initially empty.
  255.             4) A block of data longer than 16 to 18 bytes (depth of the
  256.                FIFOs plus 1 or 2 for what gets out while the FIFOs are
  257.                being filled up) is sent to the chip.
  258.  
  259.          Under these conditions the WD16550 UART will momentarily fail
  260.          to recognize the FIFOs are full and continue to generate
  261.          transmit interrupts.  It also fails to reset the 'Transmit Hold
  262.          Register Empty' bit making it impossible for the software to
  263.          detect a full FIFO condition.  The result is the software keeps
  264.          sending data to the chip, overrunning the FIFOs.  What you will
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.                             NOTES ON 16550 FIFO MODE
  272.  
  273.          see is, the first 16 to 18 bytes transmitted correctly, a
  274.          missing block of data, and then the remainder of the block also
  275.          correct.  This can be verified by trying to send blocks of data
  276.          through this chip (WD16550) at a low baud rate with any
  277.          software that enables the FIFOs.  How low of a baud rate is low
  278.          enough to cause the problem depends on the particular chip and
  279.          how fast the CPU and software can supply data to the chip.
  280.          With MCOMM, a 20 MHZ 386, and the TxByteCnt at the default
  281.          level of 3, the chip I was testing would not work in FIFO mode
  282.          below 9600 baud.  On the same system using different software,
  283.          it worked as low as 4800 baud.  On a 12 MHZ 286, MCOMM would
  284.          work at 4800 and above while the other software worked at 2400
  285.          and above.
  286.  
  287.          For publicly distributed applications, I recommend you do one
  288.          or more of the following:
  289.  
  290.             1) Provide an option in your program to allow the end user
  291.                to operate a 16550 with the FIFOs disabled.  When the
  292.                FIFOs are disabled, all baud rates work.  ORing the
  293.                ComBase parameter of async_open with 0x4000 will force
  294.                FIFO mode off.
  295.             2) Provide an option in your program to allow setting the
  296.                TxByteCnt level (async_FIFOtxlvl) to a lower value.  This
  297.                will help slightly.
  298.  
  299.             3) Put a flag in your program the end user can set to let
  300.                you know you are dealing with a WD16550.
  301.  
  302.             4) State your application does not support the Western
  303.                Digital version of the 16550 at low baud rates.
  304.  
  305.  
  306.          The second problem with the WD16550 is that if the 'Clear to
  307.          Send' signal is not connected it can, under some conditions,
  308.          cause the 'Delta Clear to Send' bit in the Modem Status
  309.          Register to become set and it will not reset.  I did not
  310.          research the problem enough to know if the 'locked bit' only
  311.          occurs when MSR interrupts are enabled, whether other floating
  312.          MSR input signals can cause the same problem, if all WD16550's
  313.          have the problem, or that is unique to the Western Digital chip
  314.          (considering the FIFO overrun problem, I assume it is unique).
  315.  
  316.          With a properly functioning UART, reading the MSR register will
  317.          reset all the 'delta bits' and clear any interrupts.  With the
  318.          chip I had, I tried everything I could think of to clear the
  319.          interrupt and nothing worked except the ON/OFF switch.  I tried
  320.          clearing interrupts and reading the MSR multiple times checking
  321.          to see if the bit reset with interrupts off (it didn't),
  322.          disabling Modem Status interrupts via the Interrupt Enable
  323.          Register and then reading the MSR register (didn't work), FIFO
  324.          mode on / FIFO mode off (no difference), keyboard reboot of the
  325.          computer (didn't fix it), shut the computer off and turn it
  326.          back on (that fixed it).
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.                             NOTES ON 16550 FIFO MODE
  334.  
  335.          After encountering this problem and having the system lock up,
  336.          I added code to MCOMM's interrupt driver so that it would quit
  337.          trying to clear an interrupt after 1000 attempts.  It then sets
  338.          a new port structure member 'IERVal' to zero as an indicator
  339.          the port is locked up.  Normally 'IERVal' will be set to the
  340.          current value of the Interrupt Enable Register.  If you try to
  341.          open a port that is in a stuck interrupt condition, async_open
  342.          now returns R_UARTERR.  In addition, options were added to open
  343.          a port without enabling Modem Status interrupts or Line Status
  344.          interrupts or both.  ORing the ComBase parameter of async_open
  345.          with 0x2000 disables MSR interrupts.  ORing with 0x1000
  346.          disables LSR interrupts.  So far I have encountered no reason
  347.          for disabling LSR interrupts.  Disabling MSR interrupts
  348.          prevents the lock up problem but has the side effect of causing
  349.          all functions and variables that use Modem Status signals to be
  350.          invalid.  This includes hardware handshake and carrier detect.
  351.  
  352.          I have probably over emphasized the Modem Status lock up
  353.          problem and my personal opinion is that it is not that serious.
  354.          I considered totally disregarding it since it has a simple
  355.          solution and that is to connect all Modem Status input signals
  356.          to some driving signal (wire the RS232 cable right).  Unused
  357.          signals can be connected to a driving signal on the computer
  358.          end if necessary.  Also it may be isolated to one defective
  359.          chip.  I tested two WD16550s and the problem only showed up on
  360.          one of them during my testing.  Because the computer totally
  361.          locked up when this happened though, I decided to go ahead and
  362.          program for the possibility.  At least control of the computer
  363.          is regained and you can tell the user he needs a properly wired
  364.          RS232 cable or his UART is broke and then exit gracefully.
  365.          This will probably show up very very rarely so don't be too
  366.          concerned about it.  In closing, I would like to point out
  367.          again that these problems are a fault of the WD16550 and are
  368.          not unique to MCOMM.
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.          async_16550
  376.          ---------------------------------------------------------------
  377.  
  378.          Purpose: Check if 16550 UART was detected in system.
  379.  
  380.          Format:  int async_16550(port);
  381.                    ASYNC *port;       Pointer to ASYNC structure
  382.  
  383.          Example:
  384.  
  385.                   ASYNC *port;
  386.                   int is_16550;
  387.  
  388.                   is_16550 = async_16550(port);
  389.  
  390.          Returns: Returns zero if a 16550 is not in the system or the
  391.                   'ignore 16550 bit' was set when async_open was called.
  392.                   Returns NZ if a 16550 was found.  Async_open must be
  393.                   called before this function is valid.  If a 16550 is
  394.                   found, it will be placed in the FIFO mode of operation
  395.                   by async_open unless '16550 detect' was overridden or
  396.                   the force FIFOs off option was selected.
  397.  
  398.          Remarks: This function is implemented as a macro.
  399.  
  400.                   See async_open.
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.          async_breakrxd
  408.          ---------------------------------------------------------------
  409.  
  410.          Purpose: Checks if a break signal has been received.
  411.  
  412.          Format:  int async_breakrxd(port);
  413.                    ASYNC *port;       Pointer to ASYNC structure
  414.  
  415.          Example:
  416.  
  417.                   ASYNC *port;
  418.                   int break_status;
  419.  
  420.                   break_status = async_breakrxd(port);
  421.  
  422.  
  423.          Returns: If a break signal has been received the function
  424.                   returns a non-zero value.  If a break has not been
  425.                   detected, zero is returned.
  426.  
  427.          Remarks: Once a break signal has been detected, this function
  428.                   continually returns non-zero values until async_reset
  429.                   is called.  If a break is received, a line status
  430.                   register interrupt is generated.  The interrupt
  431.                   handler sets a bit in the Stat1 port structure member.
  432.                   The async_breakrxd function is a macro that checks the
  433.                   status of this bit.
  434.  
  435.                   See also async_reset, async_rx, async_stat,
  436.                   async_sndbrk.
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.          async_carrier
  444.          ---------------------------------------------------------------
  445.  
  446.          Purpose: Check for the presence of a carrier.
  447.  
  448.          Format:  int async_carrier(port);
  449.                    ASYNC *port;       Pointer to ASYNC structure
  450.  
  451.          Example:
  452.  
  453.                   ASYNC *port;
  454.                   int carrier_status;
  455.  
  456.                   carrier_status = async_carrier(port);
  457.  
  458.  
  459.          Returns: A non-zero value is returned if a carrier is present.
  460.                   If the carrier detect line is LOW, zero is returned.
  461.  
  462.          Remarks: This function is implemented as a macro.  See also
  463.                   async_rx and async_stat.
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.          async_close
  471.          ---------------------------------------------------------------
  472.  
  473.          Purpose: Closes a port opened by async_open.
  474.  
  475.          Format:  int async_close(port);
  476.                    ASYNC *port;    Pointer to ASYNC structure
  477.  
  478.          Example:
  479.  
  480.                   ASYNC port;
  481.                   async_close(&port);
  482.  
  483.          Returns: No return value
  484.  
  485.          Remarks: Do not attempt to close an unopened port.  Some
  486.                   minimal checking is done internally by async_close in
  487.                   an attempt to detect whether or not the specified port
  488.                   is actually opened.  If an unopened port makes it past
  489.                   those checks and the main close routine is entered,
  490.                   the system may lock up (immediately, 2 hours later, or
  491.                   never).  When a port is closed the UART registers,
  492.                   interrupt controller mask, and interrupt vectors are
  493.                   restored to the value they had when async_open was
  494.                   called.  It is possible to close the port and leave
  495.                   various signals (DTR for one) in the state you desire
  496.                   rather than in their initial state.  See async_dtr and
  497.                   async_rts for some examples on how to do this.
  498.  
  499.                   The B_ORGFIFO bit in the ASYNC 'Stat3' structure
  500.                   member is used by async_close to return the 16550 --
  501.                   if present -- to the mode it was in when async_open
  502.                   was called.  FIFOs may be 'forced' to remain enabled
  503.                   or 'forced' to be disabled when closing the port by
  504.                   first setting or resetting this bit.  Ex:
  505.  
  506.                     Force off:    port->Stat3 &= ~B_ORGFIFO;
  507.                                   async_close(port);
  508.  
  509.                     Force on:     port->Stat3 |= B_ORGFIFO;
  510.                                   async_close(port);
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.          async_cts
  518.          ---------------------------------------------------------------
  519.  
  520.          Purpose: Check status of the Clear to Send signal.
  521.  
  522.          Format:  int async_cts(port);
  523.                    ASYNC *port;       Pointer to ASYNC structure
  524.  
  525.          Example:
  526.  
  527.                   ASYNC *port;
  528.                   int cts_status;
  529.  
  530.                   cts_status = async_cts(port);
  531.  
  532.          Returns: Returns zero if Clear To Send is LOW.  If CTS is HIGH,
  533.                   a non-zero value is returned.
  534.  
  535.          Remarks: This function is implemented as a macro.
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.          async_dsr
  543.          ---------------------------------------------------------------
  544.  
  545.          Purpose: Check status of the Data Set Ready signal.
  546.  
  547.          Format:  int async_dsr(port);
  548.                    ASYNC *port;       Pointer to ASYNC structure
  549.  
  550.          Example:
  551.  
  552.                   ASYNC *port;
  553.                   int dsr_status;
  554.  
  555.                   dsr_status = async_dsr(port);
  556.  
  557.          Returns: Returns zero if Data Set Ready is LOW.  If DSR is
  558.                   HIGH, a non-zero value is returned.
  559.  
  560.          Remarks: This function is implemented as a macro.
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.          async_dtr
  568.          ---------------------------------------------------------------
  569.  
  570.          Purpose: Set or reset the Data Terminal Ready signal.
  571.  
  572.          Format:  void async_dtr(port, DTRflag);
  573.                    ASYNC *port;       Pointer to ASYNC structure
  574.                    int DTRflag;       Set/Reset DTR flag
  575.  
  576.          Example:
  577.  
  578.                   ASYNC *port;
  579.  
  580.                   if (WantToDropDTR)
  581.                       async_dtr(port, 0);
  582.                   else if (WantDTRhigh)
  583.                       async_dtr(port, 1);
  584.  
  585.  
  586.          Returns: No return value
  587.  
  588.          Remarks: This signal is set HIGH when a port is first opened.
  589.                   When the port is closed, it is restored to the cond-
  590.                   ition it was in when the port was opened.  To force
  591.                   DTR low when a port is closed, regardless of its state
  592.                   when the port was opened, AND the port member, OldMCR,
  593.                   with NOT B_DTR.  To force DTR to remain high when the
  594.                   port is closed, OR OldMCR with B_DTR.
  595.  
  596.                     Force low:    port->OldMCR &= ~B_DTR;
  597.                                   async_close(port);
  598.  
  599.                     Force high:   port->OldMCR |= B_DTR;
  600.                                   async_close(port);
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.          async_FIFOrxlvl  <5.20 addition>
  608.          ---------------------------------------------------------------
  609.  
  610.          Purpose: Set the 16550 UART's receive trigger level.
  611.  
  612.          Format:  void async_FIFOrxlvl(port, trigger_lvl);
  613.                    ASYNC *port;       Pointer to ASYNC structure
  614.                    int trigger_lvl;   Rx FIFO interrupt trigger level
  615.  
  616.          Example:
  617.  
  618.                   ASYNC *port;
  619.  
  620.                    /* set the receiver trigger level to 8 bytes */
  621.                   async_FIFOrxlvl(port, 8);
  622.  
  623.          Returns: No return value
  624.  
  625.          Remarks: Valid values for 'trigger_lvl' are 1, 4, 8, and 14
  626.                   bytes.  When a port with a 16550 UART is first opened,
  627.                   the trigger level is set to 1 byte.  See the
  628.                   discussion on 'Use of receiver FIFOs' at the beginning
  629.                   of this document.  This function has no effect if the
  630.                   FIFOs were not enabled when async_open was called.
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.          async_FIFOtxlvl  <5.20 addition>
  638.          ---------------------------------------------------------------
  639.  
  640.          Purpose: Set the number of bytes loaded into the 16550 UART's
  641.                   transmit FIFOs when a transmit interrupt occurs.
  642.  
  643.          Format:  void async_FIFOtxlvl(port, bytes);
  644.                    ASYNC *port;       Pointer to ASYNC structure
  645.                    int bytes;         # of bytes to load into tx FIFOs
  646.  
  647.          Example:
  648.  
  649.                   ASYNC *port;
  650.  
  651.                    /* set the transmit FIFO byte level to 16 bytes */
  652.                   async_FIFOrxlvl(port, 16);
  653.  
  654.          Returns: No return value
  655.  
  656.          Remarks: Valid values for 'bytes' are 1 through 16 bytes.  When
  657.                   a port with a 16550 UART is first opened, the transmit
  658.                   level byte count is set to 3 bytes.  See the
  659.                   discussion on 'Use of transmit FIFOs' at the beginning
  660.                   of this document.  This function has no effect if the
  661.                   FIFOs were not enabled when async_open was called.
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.          async_ignerr
  669.          ---------------------------------------------------------------
  670.  
  671.          Purpose: Set or reset 'ignore characters with errors' bit
  672.  
  673.          Format:  void async_ignerr(port, flag);
  674.                    ASYNC *port;       Pointer to ASYNC structure
  675.                    int flag;          Set/Reset flag
  676.  
  677.          Example:
  678.  
  679.                   ASYNC *port;
  680.  
  681.                   if (WantToDiscardErrChars)
  682.                       async_ignerr(port, 1);
  683.                   else if (WantToKeepErrChars)
  684.                       async_ignerr(port, 0);
  685.  
  686.  
  687.          Returns: No return value
  688.  
  689.          Remarks: This function sets the bit that determines what hap-
  690.                   pens to received characters that have parity or fram-
  691.                   ing errors.  If the function is called with the flag
  692.                   set to one, incoming characters that have framing or
  693.                   parity errors are discarded -- they do not get put
  694.                   into the receive ring buffer.  If the flag is 0, char-
  695.                   acters with errors are not ignored, they are put into
  696.                   the ring buffer.  The error bits in Stat1 that reflect
  697.                   these error conditions are set regardless of the
  698.                   setting of the discard flag.  When a port is first
  699.                   opened, the flag is set to 0.  This function is imple-
  700.                   mented as a macro.
  701.  
  702.                   See also async_stat.
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.          async_msr
  710.          ---------------------------------------------------------------
  711.  
  712.          Purpose: Get the contents of the Modem Status Register.
  713.  
  714.          Format:  int async_msr(port);
  715.                    ASYNC *port;       Pointer to ASYNC structure
  716.  
  717.          Example:
  718.  
  719.                   ASYNC *port;
  720.                   int MSRcontents;
  721.  
  722.                   MSRcontents = async_msr(port);
  723.  
  724.  
  725.          Returns: The contents of the Modem Status Register.
  726.  
  727.          Remarks: This function is a macro that returns the port struc-
  728.                   ture member, MSRVal.  This value is initialized when a
  729.                   port is first opened and then updated any time a modem
  730.                   status interrupt occurs.  The reason the MSR is not
  731.                   read directly is to avoid inadvertently intercepting a
  732.                   pending MSR interrupt.  All bits returned except for
  733.                   the delta bits reflect the true current status.
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.          async_msrflow
  741.          ---------------------------------------------------------------
  742.  
  743.          Purpose: Enables or disables hardware flow control.
  744.  
  745.          Format:  void async_msrflow(port, flowmask);
  746.                    ASYNC *port;       Pointer to ASYNC structure
  747.                    int flowmask;      Bit mapped flow control mask
  748.  
  749.          Example:
  750.  
  751.                   ASYNC *port;
  752.  
  753.                   if (enable_RTS_CTS_handshake)
  754.                       async_msrflow(port, B_CTS);
  755.                   else if (disable_handshake)
  756.                       async_msrflow(port, 0);
  757.  
  758.          Returns: No return value
  759.  
  760.          Remarks: The flow mask is a bit mapped value of the signal that
  761.                   is monitored by the receiver when performing flow
  762.                   control.  Bits that may be monitored are B_CTS, B_DSR,
  763.                   and B_CD.  This provides capability for RTS/CTS hand-
  764.                   shake, DTR/DSR handshake, and handshaking with the
  765.                   carrier detect line.  To monitor multiple signals, OR
  766.                   the bits together.  Both hardware flow control and
  767.                   XON/XOFF flow control may be enabled at the same time.
  768.  
  769.                   See async_xflow.
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.          async_open  <5.40 modified -- see Remarks at end of function>
  777.          ---------------------------------------------------------------
  778.  
  779.          Purpose: Initializes the hardware, interrupt vector, and ASYNC
  780.                   port structure for interrupt driven operation.
  781.  
  782.          Format:
  783.                   int async_open(port, base, irqmask, vctrnbr, params);
  784.                    ASYNC *port;   Pointer to ASYNC structure
  785.                    int base;      Base port address of UART chip
  786.                    int irqmask;   8259 mask value for selected IRQ line
  787.                    int vctrnbr;   Number of selected interrupt vector
  788.                    char *params;  Baud, parity, data, & stop bits in
  789.                                    string format
  790.  
  791.          Entry:   Before calling this function you must allocate ring
  792.                   buffer memory and pre-initialize the following ASYNC
  793.                   structure members:
  794.  
  795.                    RxSize : the size that you want the receive ring
  796.                       buffer to be.  The memory allocated or set aside
  797.                       for the receive ring buffer must be contiguous
  798.                       with the memory used for the transmit  ring
  799.                       buffer.  In most cases (RxSize + TxSize) bytes
  800.                       will be allocated using some form of malloc.
  801.                       A function to do this is included in the examples.
  802.                       The combined size of RxSize + TxSize can not
  803.                       exceed 32K - 1.
  804.  
  805.                    TxSize : the size of the transmit buffer in bytes.
  806.                       As stated above, the transmit and receive buffers
  807.                       for each individual port must be allocated as one
  808.                       contiguous block.
  809.  
  810.                    RingSeg: the segment address of the memory allocated
  811.                       for the receive and transmit buffers.  FAR memory
  812.                       can be used for the receive and transmit buffers
  813.                       by using your compiler library's version of FAR
  814.                       malloc and putting the segment portion (high 16
  815.                       bits) of the returned memory pointer in RingSeg.
  816.                       If you are using a NEAR data model program and
  817.                       want NEAR ring buffers, set RingSeg equal to 0.
  818.                       With RingSeg set to zero, the open function will
  819.                       use the DS segment register for RingSeg.  Using
  820.                       FAR ring buffers causes no loss of performance.
  821.  
  822.                   RingOfst: the offset address of the memory allocated
  823.                       for the receive and transmit buffers.  This value,
  824.                       in conjunction with the RxSize and TxSize vari-
  825.                       ables, is used to set up the receive and transmit
  826.                       ring buffers.
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.          async_open
  834.          ---------------------------------------------------------------
  835.  
  836.                   THE FOLLOWING FUNCTION IS INCLUDED WITH MCOMM5 AND IS
  837.                   RECOMMENDED FOR ALLOCATING RING BUFFER MEMORY AND
  838.                   INITIALIZING THE ABOVE VARIABLES.
  839.  
  840.          #if defined (__TURBOC__)         /* Turbo C */
  841.             #include <alloc.h>
  842.             #define _fmalloc farmalloc
  843.          #elif defined (__ZTC__)          /* Zortech C */
  844.             #include <dos.h>
  845.             #include <stdlib.h>
  846.             #define _fmalloc farmalloc
  847.          #else                            /* Microsoft C */
  848.             #include <malloc.h>
  849.          #endif
  850.  
  851.          int AllocRingBuffer(
  852.           ASYNC *port,                  /* pointer to port structure */
  853.           int rxsize,      /* number bytes to use for receive buffer */
  854.           int txsize,     /* number bytes to use for transmit buffer */
  855.           int useFARmem)    /* flag set if using FAR mem for buffers */
  856.          {
  857.             unsigned long memptr;
  858.             int memsize;
  859.  
  860.             memsize = rxsize + txsize;
  861.  
  862.             if (useFARmem || sizeof(char *) == 4)/* if FAR Ring bufs */
  863.                memptr = (unsigned long)_fmalloc(memsize);
  864.             else                  /* if Ring buffers use NEAR memory */
  865.                memptr = (unsigned long)(unsigned int)malloc(memsize);
  866.  
  867.              /* pre-initialize 4 required structure members */
  868.             port->RxSize = rxsize;            /* receive buffer size */
  869.             port->TxSize = txsize;           /* transmit buffer size */
  870.             port->RingSeg = (int)(memptr >> 16);          /* SEG adr */
  871.             port->RingOfst = (int)memptr;            /* OFST address */
  872.             if (memptr == 0L)
  873.                return 0;          /* return 0 if no memory available */
  874.             return 1;                   /* return 1, had some memory */
  875.          }
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.          async_open
  883.          ---------------------------------------------------------------
  884.  
  885.          Example 1:
  886.  
  887.             /*
  888.                Open COM1 at 2400,N,8,1 using FAR ring buffers. COM1 is
  889.                defined in COMM.H as:  0x3f8, 0x10, 12.  It is not
  890.                necessary to check the return value of AllocRingBuffer
  891.                since async_open will return R_NOMEM if the memory
  892.                allocation function fails.
  893.             */
  894.  
  895.             #include "comm.h"
  896.  
  897.             ASYNC port;
  898.             int rcode;
  899.  
  900.             AllocRingBuffer(&port, 24000, 8000, 1);
  901.  
  902.             rcode = async_open(&port, COM1, "2400N81");
  903.           /**  or
  904.             rcode = async_open(&port, 0x3f8, 0x10, 12, "2400N81");
  905.            **  or
  906.             rcode = async_open(&port, 0x3f8, IRQ4, VCTR4, "2400N81");
  907.            **/
  908.  
  909.             if (rcode != R_OK)
  910.             {
  911.                 printf("\nAsync_open failed, exit code = %d", rcode);
  912.                 exit(rcode);
  913.             }
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.          async_open
  921.          ---------------------------------------------------------------
  922.  
  923.          Example 2:
  924.  
  925.             /*
  926.                Open a port located at 0x2e0 that uses IRQ3.  In this
  927.                case NEAR ring buffers are specified and the memory for
  928.                the port structure is obtained using malloc.  See the
  929.                AllocRingBuffer function described previously.
  930.             */
  931.  
  932.             #include "comm.h"
  933.  
  934.             ASYNC *port;
  935.             int rcode;
  936.  
  937.             if ((port = (ASYNC *)malloc(sizeof ASYNC)) == NULL)
  938.             {
  939.                 printf("\nNot enough memory");
  940.                 exit(R_NOMEM);
  941.             }
  942.  
  943.             AllocRingBuffer(port, 4096, 1200, 0);
  944.  
  945.             rcode = async_open(port, 0x2e0, IRQ3, VCTR3, "115200E71");
  946.  
  947.             if (rcode != R_OK)
  948.             {
  949.                 printf("\nAsync_open failed, exit code = %d", rcode);
  950.                 exit(rcode);
  951.             }
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.          async_open
  959.          ---------------------------------------------------------------
  960.  
  961.          Example 3:
  962.  
  963.             /*
  964.                Open both COM1 and COM2 at the same time.  You can open
  965.                two ports at once as long as they don't share the same
  966.                IRQ line or interrupt vector.
  967.             */
  968.  
  969.             #include "comm.h"
  970.  
  971.             ASYNC ports[2], *port[2];
  972.             int rcode;
  973.  
  974.             port[0] = &ports[0], port[1] = &ports[1];
  975.  
  976.             AllocRingBuffer(port[0], 10240, 10240, 1);
  977.             rcode = async_open(port[0], COM1, "9600N81");
  978.             if (rcode != R_OK)
  979.             {
  980.                 printf("\nAsync_open failed, exit code = %d", rcode);
  981.                 exit(rcode);
  982.             }
  983.  
  984.             AllocRingBuffer(port[1], 10240, 10240, 1);
  985.             rcode = async_open(port[1], COM2, "1200E71");
  986.             if (rcode != R_OK)
  987.             {
  988.                 printf("\nAsync_open failed, exit code = %d", rcode);
  989.                 exit(rcode);
  990.             }
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.          async_open
  998.          ---------------------------------------------------------------
  999.  
  1000.          Example 4:
  1001.  
  1002.             /*
  1003.                Open COM1 using its current baud, parity, data, and
  1004.                stop bit settings.  The port structure member, BPDSstr,
  1005.                will reflect those settings after calling async_open.
  1006.             */
  1007.  
  1008.             #include "comm.h"
  1009.  
  1010.             ASYNC *port;
  1011.             int rcode;
  1012.  
  1013.              /* alloc port structure & ring buffer memory */
  1014.             port = malloc(sizeof(ASYNC));
  1015.             AllocRingBuffer(port, 4096, 2048, 1);
  1016.  
  1017.              /* empty parameter string causes port to be opened at
  1018.                 its current settings  */
  1019.             rcode = async_open(port, COM1, "");
  1020.  
  1021.             if (rcode != R_OK)
  1022.             {
  1023.                 printf("\nAsync_open failed, exit code = %d", rcode);
  1024.                 exit(rcode);
  1025.             }
  1026.  
  1027.             printf(
  1028.              "\nBaud, parity, data, stop bits = %s\n", port->BPDSstr);
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.          async_open
  1036.          ---------------------------------------------------------------
  1037.  
  1038.          Returns:
  1039.  
  1040.                   R_OK (0) - the port was opened with no errors.
  1041.  
  1042.                   R_NOMEM - a NULL pointer was passed as the address
  1043.                       of the ring buffers.  Probable causes are either
  1044.                       failing to initialize the port structure ring
  1045.                       buffer variables or assigning the RingSeg and
  1046.                       RingOfst structure a NULL pointer.  This could
  1047.                       occur if you use the AllocRingBuffer function or
  1048.                       something similar and the call to malloc fails.
  1049.  
  1050.                   R_BAUDERR - the passed baud rate in the BPDS string
  1051.                       was invalid.  Some possible reasons for this error
  1052.                       are leading spaces in the parameter string or use
  1053.                       of commas.  "115200N81" is correct. " 115200N81"
  1054.                       and "115,200N81" are both incorrect.
  1055.  
  1056.                   R_PARITYERR - an invalid character was found in the
  1057.                       parameter string where the parity should have
  1058.                       been.  Commas or spaces in the parameter string
  1059.                       are possible causes.  Valid parity settings are N
  1060.                       - none, E - even, or O - odd.  See R_BAUDERR.
  1061.  
  1062.                   R_DTABITERR - an invalid number of data bits was spec-
  1063.                       ified.  Only settings of 7 or 8 are supported.
  1064.  
  1065.                   R_STPBITERR - an invalid number of stop bits was spec-
  1066.                       ified.  Stop bits must be set to either 1 or 2.
  1067.  
  1068.                   R_IRQUSED - an attempt was made to open two ports that
  1069.                       use the same IRQ line.
  1070.  
  1071.                   R_VCTRUSED - an attempt was made to open two ports
  1072.                       that use the same interrupt vector.
  1073.  
  1074.                   R_NOPORT - an attempt was made to open more than 2
  1075.                       simultaneous ports.
  1076.  
  1077.                   R_PORTUSED - an attempt was made to open two ports
  1078.                       that have the same I/O address.
  1079.  
  1080.                   R_UARTERR - an attempt was made to open a port that is
  1081.                       stuck in an interrupt condition (see the notes on
  1082.                       problems with the WD16550 at the beginning of this
  1083.                       documentation ).
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.          async_open
  1091.          ---------------------------------------------------------------
  1092.  
  1093.          Remarks (16550 support):
  1094.  
  1095.                   This function now automatically detects the presence
  1096.                   of a 16550 UART and enables FIFO operation if one is
  1097.                   detected.  By ORing either 0x8000 or 0x4000 with the
  1098.                   ComBase argument, you can change the default of auto-
  1099.                   enabling FIFO mode.  If 0x8000 is ORed with the
  1100.                   ComBase argument (ex: 0x8000|0x3f8), no attempt is
  1101.                   made to detect a 16550 and no changes are made to the
  1102.                   mode of operation of the 16550 if one is present.  If
  1103.                   this bit is set, none of the functions or bits
  1104.                   relating to the 16550 UART will be valid.  If 0x4000
  1105.                   is ORed with the ComBase, the 16550 will be forced
  1106.                   into non-FIFO mode.
  1107.  
  1108.                   ORing 0x2000 with the ComBase parameter will open the
  1109.                   port with MSR interrupts disabled.  ORing the ComBase
  1110.                   parameter with 0x1000 will open the port with LSR
  1111.                   interrupts disabled.  See the notes on the WD16550 at
  1112.                   the beginning of this documentation for why this may
  1113.                   be desired and the side effects of opening a port with
  1114.                   MSR interrupts disabled.
  1115.  
  1116.                   When async_open is called, the FIFOs are momentarily
  1117.                   disabled and then re-enabled with the receive trigger
  1118.                   level set to 1 byte.  In versions of MCOMM prior to
  1119.                   5.40, the FIFOs were not reset if they were already
  1120.                   on.  Resetting the FIFOs was added to correct
  1121.                   occasional rare problems with the port not opening.
  1122.  
  1123.                     /* detect 16550, enable FIFOs if present */
  1124.                   async_open(PortPtr, 0x3f8, IRQ, Vector, Params);
  1125.  
  1126.                    /* do not attempt to detect 16550 */
  1127.                   async_open(PortPtr, 0x8000|0x3f8, IRQ, Vctr, Params);
  1128.  
  1129.                    /* detect 16550, disable FIFOs if present */
  1130.                   async_open(PortPtr, 0x4000|0x3f8, IRQ, Vctr, Params);
  1131.  
  1132.                    /* open port, disable MSR interrupts */
  1133.                   async_open(PortPtr, 0x2000|0x3f8, IRQ, Vctr, Params);
  1134.  
  1135.                    /* open port, disable MSR interrupts and FIFOs */
  1136.                   async_open(PortPtr, 0x6000|0x3f8, IRQ, Vctr, Params);
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.          async_open
  1144.          ---------------------------------------------------------------
  1145.  
  1146.          Remarks (versions previous to 5.00):
  1147.  
  1148.                   There are some major differences in the async_open
  1149.                   function in MCOMM5 and previous versions of the rou-
  1150.                   tines.  The two most major ones are that the parame-
  1151.                   ters passed to the function are different and it is
  1152.                   now necessary to allocate the memory for the ring
  1153.                   buffers before calling the function.  To make things
  1154.                   simpler, COM1 and COM2 are defined in COMM.H and the
  1155.                   function, AllocRingBuffer, is provided.  The COM1 and
  1156.                   COM2 definitions satisfy the requirements for the 2nd,
  1157.                   3rd, and 4th parameters required by the function.  For
  1158.                   ports other than the standard COM1 and COM2, it is
  1159.                   necessary to list the individual arguments.  The func-
  1160.                   tion, AllocRingBuffer, is provided in C source form on
  1161.                   the disk and included in the COMM_x libraries.  This
  1162.                   function allocates the ring buffer memory and initial-
  1163.                   izes the required port structure members.
  1164.  
  1165.                   The return values for async_open are different and may
  1166.                   have a different meaning than in earlier versions.
  1167.  
  1168.                   If a port is opened with an empty parameter string
  1169.                   (using "" for the parameters), then the port is opened
  1170.                   at its current settings and the port member BPDSstr is
  1171.                   set to the string representation of those values.
  1172.  
  1173.                   Async_open no longer checks the BIOS ram area at 40:0
  1174.                   to verify that a port actually exists.  There were too
  1175.                   many compatibles that did not store the proper values
  1176.                   there.
  1177.  
  1178.                   The maximum combined size of the receive and transmit
  1179.                   buffers for each port is 32K - 1.
  1180.  
  1181.                   FAR ring buffers in small and medium memory model
  1182.                   programs is now supported.  Use of FAR buffers does
  1183.                   not in any way affect the speed of the routines.
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.          async_peek
  1191.          ---------------------------------------------------------------
  1192.  
  1193.          Purpose: Indexed receive ring buffer look ahead function.
  1194.  
  1195.          Format:  int async_peek(port, index);
  1196.                    ASYNC *port;       Pointer to ASYNC structure
  1197.                    int index;         Index value
  1198.  
  1199.          Examples:
  1200.  
  1201.                   ASYNC *port;
  1202.                   char ch, buf[10];
  1203.                   int i;
  1204.  
  1205.                    /* peek next char in receive ring buffer */
  1206.                   ch = async_peek(port, 0);
  1207.  
  1208.                    /* peek next 10 chars in receive ring buffer */
  1209.                   for (i = 0; i < 10; i++)
  1210.                       buf[i] = async_peek(port, i);
  1211.  
  1212.          Returns: This function returns the character in the receive
  1213.                   ring buffer at the indexed position.  If an attempt is
  1214.                   made to peek deeper in the ring buffer than there are
  1215.                   characters in the ring buffer, -1 (0xffff) is
  1216.                   returned.
  1217.  
  1218.          Remarks: No characters are removed from the ring buffer by this
  1219.                   function.
  1220.  
  1221.                   The index value is 0 based.
  1222.  
  1223.                   To avoid confusing the character, '\0xff', from the
  1224.                   error return value, 0xffff, use an integer size
  1225.                   variable for the return value.  The character '\0xff'
  1226.                   is returned as 0x00ff and the error condition is
  1227.                   returned as 0xffff.
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.          async_regs
  1235.          ---------------------------------------------------------------
  1236.  
  1237.          Purpose: Provides direct access to the UART registers.
  1238.  
  1239.          Format:  int async_regs(port, reg_ofst, value);
  1240.                    ASYNC *port;       Pointer to ASYNC structure
  1241.                    int reg_ofst;      Offset of register from base adrs
  1242.                    int value;         Value to write or -1 if reading
  1243.  
  1244.          Examples:
  1245.  
  1246.                   ASYNC *port;
  1247.                   int LCRvalue;
  1248.  
  1249.                    /* read the line control register */
  1250.                   LCRvalue = async_regs(port, LCRreg, RDreg);
  1251.  
  1252.                    /* write a 0 to the modem control register */
  1253.                   async_regs(port, MCRreg, 0);
  1254.  
  1255.          Returns: When reading a register, the return value is the value
  1256.                   of the UART register that was read.  When writing a
  1257.                   register, the return value is undefined.
  1258.  
  1259.          Remarks: The following values for register offsets are defined
  1260.                   in COMM.H for use with async_regs:
  1261.                     RXreg, TXreg - receive & transmit regs, value = 0
  1262.                     IERreg - interrupt enable register,     value = 1
  1263.                     IIDreg - interrupt identification reg,  value = 2
  1264.                     FCRreg - FIFO control register          value = 2
  1265.                     LCRreg - line control register,         value = 3
  1266.                     MCRreg - modem control register,        value = 4
  1267.                     LSRreg - line status register,          value = 5
  1268.                     MSRreg - modem status register,         value = 6
  1269.                     LObaud - offset of low baud divisor,    value = 0
  1270.                     HIbaud - offset of high baud divisor,   value = 1
  1271.                   Also RDreg is defined as -1 for use when reading one
  1272.                   of the UART registers.  See the examples.  See
  1273.                   cautions on the following page before using this
  1274.                   function.
  1275.  
  1276.  
  1277.  
  1278.  
  1279.  
  1280.  
  1281.          async_regs
  1282.          ---------------------------------------------------------------
  1283.  
  1284.          Remarks (continued):
  1285.  
  1286.                   This function is provided primarily as a debugging
  1287.                   tool.  Reading or writing to the UART registers while
  1288.                   operating in an interrupt driven mode can cause
  1289.                   several types of problems.  Do not use this function
  1290.                   unless you know what you are doing.  Do not read the
  1291.                   RXreg, IIDreg, LSRreg, or MSRreg on an open port
  1292.                   except for debugging purposes.  Do not write any of
  1293.                   the registers.
  1294.  
  1295.                   The function may be used on a port that has not yet
  1296.                   been opened if the ComBase member of the port struc-
  1297.                   ture has been set.  When async_regs is used with an
  1298.                   unopened port the UART registers may be read or writ-
  1299.                   ten without restriction.
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.  
  1306.          async_reset
  1307.          ---------------------------------------------------------------
  1308.  
  1309.          Purpose: Clear parity error bit, framing error bit, character
  1310.                   overrun bit, receive buffer overflow bit, and break
  1311.                   signal received bit in the the Stat1 byte.
  1312.  
  1313.          Format:  void async_reset(port);
  1314.                    ASYNC *port;       Pointer to ASYNC structure
  1315.  
  1316.          Example:
  1317.  
  1318.                   ASYNC *port;
  1319.  
  1320.                   if (error)
  1321.                       async_reset(port);
  1322.  
  1323.  
  1324.          Returns: No return value
  1325.  
  1326.          Remarks: This function is implemented as a macro.  See also
  1327.                   async_rx and async_stat.
  1328.  
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334.          async_restart
  1335.          ---------------------------------------------------------------
  1336.  
  1337.          Purpose: Re-initialize an already opened serial port
  1338.  
  1339.          Format:  void async_restart(port);
  1340.                    ASYNC *port;       Pointer to ASYNC structure
  1341.  
  1342.          Example:
  1343.  
  1344.                   ASYNC *port;
  1345.  
  1346.                   async_restart(port);
  1347.  
  1348.  
  1349.          Returns: No return value
  1350.  
  1351.          Remarks: Async_restart resets the interrupt vector, UART regis-
  1352.                   ters, and 8259 interrupt controller mask to the values
  1353.                   necessary for interrupt driven operation.  It also
  1354.                   flushes the receive and transmit buffers and resets
  1355.                   the Stat1 byte.  Use this function to restart a comm
  1356.                   port after spawning a program that may have altered
  1357.                   the interrupt vector, UART regs, or interrupt mask.
  1358.  
  1359.                   See also async_stop.
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.          async_rts
  1367.          ---------------------------------------------------------------
  1368.  
  1369.          Purpose: Sets or resets the Request to Send signal.
  1370.  
  1371.          Format:  void async_rts(port, flag);
  1372.                    ASYNC *port;       Pointer to ASYNC structure
  1373.                    int flag;          Set/Reset RTS flag
  1374.  
  1375.          Example:
  1376.  
  1377.                   ASYNC *port;
  1378.  
  1379.                   if (WantToDropRTS)
  1380.                       async_rts(port, 0);
  1381.                   else if (WantRTShigh)
  1382.                       async_rts(port, 1);
  1383.  
  1384.  
  1385.          Returns: No return value
  1386.  
  1387.          Remarks: The RTS signal is primarily used for hardware hand-
  1388.                   shaking.  When a port is first opened RTS is set HIGH
  1389.                   (enabled).  When the port is closed, it is restored to
  1390.                   the condition it was in when the port was opened.  To
  1391.                   force RTS low when closing a port, regardless of its
  1392.                   state when the port was opened, AND the port member,
  1393.                   OldMCR with NOT B_RTS.  To force RTS to remain high
  1394.                   when the port is closed, OR OldMCR with B_RTS.
  1395.  
  1396.                     Force low:    port->OldMCR &= ~B_RTS;
  1397.                                   async_close(port);
  1398.  
  1399.                     Force high:   port->OldMCR |= B_RTS;
  1400.                                   async_close(port);
  1401.  
  1402.  
  1403.  
  1404.  
  1405.  
  1406.  
  1407.          async_rx
  1408.          ---------------------------------------------------------------
  1409.  
  1410.          Purpose: Gets one character from the receive ring buffer.
  1411.  
  1412.          Format:  int async_rx(port);
  1413.                    ASYNC *port;       Pointer to ASYNC structure
  1414.  
  1415.          Examples:
  1416.  
  1417.                   ASYNC *port;
  1418.                   int rxch;
  1419.  
  1420.                   rxch = async_rx(port);       /* rxch == Stat1/char */
  1421.  
  1422.                   rxch = async_rx(port) & 0xff;      /* rxch == char */
  1423.  
  1424.                    /* chk if char available & process only if it was */
  1425.                   if (!((rxch = async_rx(port)) & B_RXEMPTY)
  1426.                       procRxdChar(rxch & 0xff);
  1427.  
  1428.          Returns: Async_rx returns the character received as the low
  1429.                   byte and the Stat1 status byte as the high byte.  If
  1430.                   the receive ring buffer was empty when async_rx was
  1431.                   called the low byte will be 0 and the high byte will
  1432.                   have the B_RXEMPTY bit set.  The Stat1 byte is a bit
  1433.                   mapped value that reflects parity errors, framing
  1434.                   errors, character overrun errors, receive buffer
  1435.                   overflow errors, receive buffer empty, break signal
  1436.                   received, and carrier lost.  If no receive errors
  1437.                   have occurred, a break signal has not been received,
  1438.                   and a carrier is present, Stat1 will be 0.
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.          async_rx
  1446.          ---------------------------------------------------------------
  1447.  
  1448.          Remarks: Error bits set in the Stat1 byte are not necessarily
  1449.                   associated with the character just taken out of the
  1450.                   receive ring buffer.  In fact, they probably are not.
  1451.                   The error bits are set when the error is detected and
  1452.                   reset when async_reset is called.  For example:
  1453.  
  1454.                    1) 20 bytes of data are received with no errors.
  1455.                    2) Async_rx has been called 10 times so 10 characters
  1456.                       have been taken out of the ring buffer and 10 of
  1457.                       the bytes with no errors are still in the buffer.
  1458.                    3) A parity error occurs on the next byte received
  1459.                       from the UART -- the 11th byte in the receive ring
  1460.                       buffer.
  1461.                    4) The next byte taken out of the buffer, which is
  1462.                       the first of the 10 remaining good bytes will have
  1463.                       the parity error bit in the Stat1 byte.  It will
  1464.                       remain set until async_reset is called.
  1465.  
  1466.                   If the 'ignore characters with errors' bit is set (see
  1467.                   async_ignerr), then characters that have either parity
  1468.                   or framing errors are never placed in the receive ring
  1469.                   buffer.  They are read from the UART and discarded.
  1470.                   The error bits in Stat1 are set regardless of the
  1471.                   setting of the 'ignore characters with errors' bit.
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478.          async_rxblk
  1479.          ---------------------------------------------------------------
  1480.  
  1481.          Purpose: Retrieves a block of characters from the receive ring
  1482.                   buffer.
  1483.  
  1484.          Format:  int async_rxblk(port, buf, maxchars);
  1485.                    ASYNC *port;       Pointer to ASYNC structure
  1486.                    char *buf;         Buffer for received data
  1487.                    int maxchars;      Maximum number of chars to read
  1488.  
  1489.          Example:
  1490.  
  1491.                   ASYNC *port;
  1492.                   char buf[256];
  1493.                   int bytesRead;
  1494.  
  1495.                   bytesRead = async_rxblk(port, buf, sizeof(buf));
  1496.  
  1497.          Returns: Async_rxblk returns the number of bytes read.  This
  1498.                   value will be 'maxchars' if there are that many bytes
  1499.                   available in the receive buffer.  If there are not
  1500.                   'maxchars' in the receive buffer, the entire contents
  1501.                   of the receive buffer will be moved to 'buf' and the
  1502.                   return value will be the number of bytes that were in
  1503.                   the buffer.
  1504.  
  1505.          Remarks: Very fast way to read data.  See also async_rx and
  1506.                   async_rxblkch.
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.          async_rxblkch
  1514.          ---------------------------------------------------------------
  1515.  
  1516.          Purpose: Retrieve bytes from the receive ring buffer until the
  1517.                   specified character is found, 'maxchars' are read, or
  1518.                   the receive ring buffer is emptied.
  1519.  
  1520.          Format:
  1521.            int async_rxblkch(port, buf, maxchars, keychar, includekey);
  1522.             ASYNC *port;      Pointer to ASYNC structure
  1523.             char *buf;        Destination for bytes read
  1524.             int maxchars;     Maximum number of chars to read
  1525.             char keychar;     Character to scan for
  1526.             int includekey;   Flag set if 'keychar' is to be read also
  1527.  
  1528.          Example:
  1529.  
  1530.            ASYNC *port;
  1531.            char buf[256];
  1532.            int bytesRead;
  1533.            int foundkey;
  1534.  
  1535.            bytesRead = async_rxblkch(port, buf, sizeof(buf), '\n', 1);
  1536.            if (bytesRead < 0)
  1537.                bytesRead = -bytesRead, foundkey = TRUE;
  1538.             else
  1539.                foundkey = FALSE;
  1540.  
  1541.          Returns: This function returns the number of bytes read if the
  1542.                   'keychar' is not found.  If the 'keychar' is found the
  1543.                   2's complement of the number of bytes read is
  1544.                   returned.
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.          async_rxblkch
  1552.          ---------------------------------------------------------------
  1553.  
  1554.          Remarks: The 'includekey' flag, which is the last argument of
  1555.                   the function, determines whether or not the 'keychar'
  1556.                   is to be included if it is found.  If the flag is 1
  1557.                   and the 'keychar' is found it will be the last char-
  1558.                   acter in the user buffer.  If this flag is 0 and the
  1559.                   'keychar' is found, the 'keychar' is left in the re-
  1560.                   ceive ring buffer and will be the first character read
  1561.                   when you next call one of the async_rx type functions.
  1562.                   This can cause a problem if you set this flag to 0 and
  1563.                   the 'keychar' is the first character in the receive
  1564.                   buffer.  The function will return 0, which would seem
  1565.                   to indicate that there were no bytes in the buffer.
  1566.                   Actually the character was found but since you are not
  1567.                   taking it out of the ring buffer zero bytes are read.
  1568.                   There are two ways to check for this condition.  You
  1569.                   can first call async_rxcnt to verify there are bytes
  1570.                   in the receive buffer and then call async_rxblkch.  If
  1571.                   async_rxblkch returns 0, the 'keychar' is there and is
  1572.                   the first byte in the buffer.  The other method is to
  1573.                   use async_peek to see what the next character in the
  1574.                   receive buffer is before calling async_rxblkch.
  1575.  
  1576.                   A 2's complement value of the bytes read is returned
  1577.                   by async_rxblkch when the 'keychar' is found.  For
  1578.                   actual bytes use:
  1579.                       bytes = async_rxblkch( ....);
  1580.                       if (bytes < 0)
  1581.                           bytes = -bytes;
  1582.                   A byte count less than zero is the signal the
  1583.                   'keychar' was found.  (Except for the circumstance
  1584.                   noted in the previous paragraph).
  1585.  
  1586.                   See async_rx, async_rxblk, async_rxcnt, async_peek.
  1587.  
  1588.  
  1589.  
  1590.  
  1591.  
  1592.  
  1593.          async_rxcnt
  1594.          ---------------------------------------------------------------
  1595.  
  1596.          Purpose: Returns the number of bytes in the receive ring
  1597.                   buffer.
  1598.  
  1599.          Format:  int async_rxcnt(port);
  1600.                    ASYNC *port;       Pointer to ASYNC structure
  1601.  
  1602.          Example:
  1603.  
  1604.                   ASYNC *port;
  1605.  
  1606.                   BytesInRxBuf = async_rxcnt(port);
  1607.  
  1608.          Returns: Number of bytes in the receive ring buffer
  1609.  
  1610.          Remarks: This function is implemented as a macro.
  1611.  
  1612.  
  1613.  
  1614.  
  1615.  
  1616.  
  1617.          async_rxerr
  1618.          ---------------------------------------------------------------
  1619.  
  1620.          Purpose: Checks if a receive error has been detected.
  1621.  
  1622.          Format:  int async_rxerr(port);
  1623.                    ASYNC *port;       Pointer to ASYNC structure
  1624.  
  1625.          Example:
  1626.  
  1627.                   ASYNC *port;
  1628.                   int rxerr_status;
  1629.  
  1630.                   rxerr_status = async_rxerr(port);
  1631.  
  1632.          Returns: ZR if no receive errors have been detected, NZ if
  1633.                   receive error has been detected.
  1634.  
  1635.          Remarks: Types of receive errors that are detected by this
  1636.                   function are parity errors, framing errors, UART
  1637.                   receive register overflow, and receive ring buffer
  1638.                   overflow.  This information is also returned as the
  1639.                   high byte of the async_rx and async_stat functions.
  1640.                   This function is implemented as a macro.
  1641.  
  1642.                   See also async_rx, async_stat.
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.          async_rxflush
  1650.          ---------------------------------------------------------------
  1651.  
  1652.          Purpose: Empties out the receive ring buffer.
  1653.  
  1654.          Format:  void async_rxflush(port);
  1655.                    ASYNC *port;       Pointer to ASYNC structure
  1656.  
  1657.          Example:
  1658.  
  1659.                   ASYNC *port;
  1660.  
  1661.                   async_rxflush(port);
  1662.  
  1663.          Returns: This function does not have a return value
  1664.  
  1665.          Remarks: Clears the receive ring buffer and -- if a 16550 is
  1666.                   present in the system with its FIFOs activated --
  1667.                   resets the receiver FIFOs.  All data that was in the
  1668.                   buffer is lost.  If XON/XOFF flow control is being
  1669.                   used and an XOFF has been sent to the remote, this
  1670.                   function automatically sends an XON.  An XON is not
  1671.                   ALWAYS sent -- only if XFLOW control is in use and the
  1672.                   async interrupt routine has sent an XOFF.  It will not
  1673.                   clear false XOFFs the remote may have received.
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.          async_rxfree (5.40)
  1681.          ---------------------------------------------------------------
  1682.  
  1683.          Purpose: Returns the number of bytes left available in the
  1684.                   receive ring buffer for incoming characters.
  1685.  
  1686.          Format:  int async_rxfree(port);
  1687.                    ASYNC *port;       Pointer to ASYNC structure
  1688.  
  1689.          Example:
  1690.  
  1691.                   ASYNC *port;
  1692.  
  1693.                    RxBufFreeSpace = async_rxfree(port);
  1694.  
  1695.          Returns: Number of bytes that can be received without taking
  1696.                   any out before a receive buffer overflow will occur.
  1697.  
  1698.          Remarks: This function is implemented as a macro.
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.          async_setbpds
  1706.          ---------------------------------------------------------------
  1707.  
  1708.          Purpose: Change the baud rate, parity, number of data bits or
  1709.                   number of stop bits on an already opened port.
  1710.  
  1711.          Format:  int async_setbpds(port, params);
  1712.                    ASYNC *port;       Pointer to ASYNC structure
  1713.                    char *params;      Pointer to parameter string
  1714.  
  1715.          Example:
  1716.  
  1717.                   ASYNC *port;
  1718.                   int rcode;
  1719.  
  1720.                   rcode = async_setbpds(port, "2400E71");
  1721.  
  1722.          Returns: This function returns 0 if successful and the new
  1723.                   parameter string is copied to the port structure
  1724.                   member, BPDSstr.  Errors that can be returned are
  1725.                   R_BAUDERR, R_PARITYERR, R_DTABITERR, or R_STPBITERR.
  1726.                   If one of these error codes are returned, the port
  1727.                   settings are unchanged and the port member BPDSstr is
  1728.                   left unchanged.
  1729.  
  1730.                   See async_open for a more complete description of
  1731.                   these errors.
  1732.  
  1733.          Remarks: If 7 data bits is selected the StripMask is set to
  1734.                   strip the high bit off incoming data.  If 8 data bits
  1735.                   are selected the StripMask is disabled.
  1736.  
  1737.                   Valid baud rates are from 50 to 115200 baud.  Parity
  1738.                   may be 'E'ven, 'N'one, or 'O'dd.  The number of data
  1739.                   bits must be 7 or 8 and the number of stop bits must
  1740.                   be 1 or 2.  Do not use spaces, commas, or any other
  1741.                   type of punctuation in the parameter string.
  1742.  
  1743.                   See also async_open, async_strip.
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.          async_sndbrk
  1751.          ---------------------------------------------------------------
  1752.  
  1753.          Purpose: Enable or disable a break signal
  1754.  
  1755.          Format:  void async_sndbrk(port, Brkflag);
  1756.                    ASYNC *port;       Pointer to ASYNC structure
  1757.                    int Brkflag;       Set/Reset break signal flag
  1758.  
  1759.          Example:
  1760.  
  1761.                   ASYNC *port;
  1762.  
  1763.                    /* send break for 50 msec */
  1764.                   async_sndbrk(port, 1); /* enable break signal */
  1765.                   delay(50MSEC);         /* your delay function */
  1766.                   async_sndbrk(port, 0); /* disable break signal */
  1767.  
  1768.  
  1769.          Returns: No return value
  1770.  
  1771.          Remarks: This function causes the UART to send a continuous
  1772.                   break signal if it is called with the flag set to 1.
  1773.                   It must be called again with the flag set to 0 to
  1774.                   disable the break signal.
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.          async_stat
  1782.          ---------------------------------------------------------------
  1783.  
  1784.          Purpose: Get the current status of a port
  1785.  
  1786.          Format:  int async_stat(port, mask);
  1787.                    ASYNC *port;       Pointer to ASYNC structure
  1788.                    int mask;          Mask applied to return value
  1789.  
  1790.          Examples:
  1791.  
  1792.                   ASYNC *port;
  1793.                   int status;
  1794.  
  1795.                    /* status = all status bits */
  1796.                   status = async_stat(port, 0xffff);
  1797.  
  1798.                    /* check for XOFF received condition */
  1799.                   if (async_stat(port, B_XRXD))
  1800.                       do_something();
  1801.  
  1802.  
  1803.          Returns: Returns Stat1/Stat2 status bits after masking them
  1804.                   with the passed mask value.  Stat1 is the high byte
  1805.                   and Stat2 is the low byte of the return value.
  1806.  
  1807.                   Stat1 bit map:
  1808.                       Bit 7 = set if no carrier present
  1809.                       Bit 6 = receive ring buffer empty
  1810.                       Bit 5 = used by interrupt routines (always 0)
  1811.                       Bit 4 = break signal was detected
  1812.                       Bit 3 = framing error was detected
  1813.                       Bit 2 = parity error was detected
  1814.                       Bit 1 = character overrun error was detected
  1815.                       Bit 0 = receive ring buffer has overflowed
  1816.  
  1817.                   Stat2 bit map:
  1818.                       Bit 7 = carrier detect monitored for flow control
  1819.                       Bit 6 = XOFF rx'd or hardware flow control active
  1820.                       Bit 5 = data set ready monitored for flow control
  1821.                       Bit 4 = clear to send monitored for flow control
  1822.                       Bit 3 = transmit ring buffer is empty
  1823.                       Bit 2 = an XOFF has been sent by interrupt handler
  1824.                       Bit 1 = an XOFF has been received
  1825.                       Bit 0 = using XON/XOFF flow control
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.          async_stat
  1833.          ---------------------------------------------------------------
  1834.  
  1835.          Remarks: For some situations, it is more efficient to use one
  1836.                   of the other library functions targeted specifically
  1837.                   for the information you want.  For instance, instead
  1838.                   of calling:
  1839.                        async_stat(port, B_XRXD);
  1840.                   use:
  1841.                        async_xrxd(port);
  1842.  
  1843.                   The information in the Stat1 byte is also returned as
  1844.                   the high byte of the async_rx function.  Bits 0-4 of
  1845.                   Stat1 remain set until cleared by the async_reset
  1846.                   function.
  1847.  
  1848.                   Not all bits in the Stat2 and Stat1 port structure
  1849.                   members are kept updated on a constant basis so do not
  1850.                   try to check a condition by testing the Stat1 or Stat2
  1851.                   values in the ASYNC structure.  Use one of the docu-
  1852.                   mented functions or macros to be sure of getting the
  1853.                   correct result.
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.          async_stop
  1861.          ---------------------------------------------------------------
  1862.  
  1863.          Purpose: Temporarily disables interrupt driven operation of an
  1864.                   already opened port.
  1865.  
  1866.          Format:  void async_stop(port);
  1867.                    ASYNC *port;       Pointer to ASYNC structure
  1868.  
  1869.          Example:
  1870.  
  1871.                   ASYNC *port;
  1872.                   int x, inhdl, outhdl, errhdl;
  1873.  
  1874.                   async_stop(port);               /* release port */
  1875.                    /* redirect console to async port */
  1876.                   x = open("COM1", O_RDWR|O_BINARY);
  1877.                   inhdl = dup(0);  outhdl = dup(1);  errhdl = dup(2);
  1878.                   dup2(x, 0);  dup2(x, 1);  dup2(x, 2);
  1879.                    /* run a redirected DOS shell */
  1880.                   spawnlp(P_WAIT, "COMMAND.COM", "COMMAND.COM", NULL);
  1881.                    /* restore stdin, stdout, stderr */
  1882.                   close(x);
  1883.                   dup2(inhdl, 0);   close(inhdl);
  1884.                   dup2(outhdl, 1);  close(outhdl);
  1885.                   dup2(errhdl, 2);  close(errhdl);
  1886.                   async_restart(port);   /* regain control of port */
  1887.  
  1888.          Returns: No return value
  1889.  
  1890.          Remarks: Call this function before spawning a program that will
  1891.                   be doing its own port I/O, such as an external commun-
  1892.                   ications program or a redirected DOS shell.  After the
  1893.                   other application has completed, call async_restart to
  1894.                   re-enable interrupt operation.
  1895.  
  1896.                   This function disables interrupts for the named port
  1897.                   by clearing UART's interrupt enable register and the
  1898.                   OUT2 bit of its modem control register.
  1899.  
  1900.                   See also async_restart.
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.          async_strip
  1908.          ---------------------------------------------------------------
  1909.  
  1910.          Purpose: Set the strip mask for received characters.
  1911.  
  1912.          Format:  void async_strip(port, mask);
  1913.                    ASYNC *port;       Pointer to ASYNC structure
  1914.                    char mask;         Strip mask
  1915.  
  1916.          Example:
  1917.  
  1918.                   ASYNC *port;
  1919.  
  1920.                   async_strip(port, '\x7f');
  1921.  
  1922.          Returns: No return value
  1923.  
  1924.          Remarks: The strip mask is automatically set to 0x7f when the
  1925.                   parameters are set for 7 data bits and to 0xff when 8
  1926.                   data bits are used.  All incoming data is ANDed with
  1927.                   the strip mask before it is placed in the receive ring
  1928.                   buffer.  This function is implemented as a macro.
  1929.  
  1930.  
  1931.  
  1932.  
  1933.  
  1934.  
  1935.          async_tx
  1936.          ---------------------------------------------------------------
  1937.  
  1938.          Purpose: Send 1 character to a port.
  1939.  
  1940.          Format:  int async_tx(port, ch);
  1941.                    ASYNC *port;       Pointer to ASYNC structure
  1942.                    char ch;           Character to transmit
  1943.  
  1944.          Example:
  1945.  
  1946.                   ASYNC *port;
  1947.  
  1948.                    /* send a CR/LF to a port */
  1949.                   async_tx(port, '\r');
  1950.                   async_tx(port, '\n');
  1951.  
  1952.  
  1953.          Returns: Returns the number of bytes left available in the
  1954.                   transmit ring buffer unless the ring buffer was full
  1955.                   when the function was called.  R_TXERR is returned if
  1956.                   the transmit ring buffer was full and the character
  1957.                   that was to be transmitted is not placed in the ring
  1958.                   buffer.
  1959.  
  1960.          Remarks: The error return value, R_TXERR, is a negative number.
  1961.                   The bytes free return value can never be negative.
  1962.  
  1963.                   See also async_txblk, async_txfree.
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.          async_txblk
  1971.          ---------------------------------------------------------------
  1972.  
  1973.          Purpose: Send a block of characters to a port.
  1974.  
  1975.          Format:  int async_txblk(port, buf, count);
  1976.                    ASYNC *port;       Pointer to ASYNC structure
  1977.                    char *buf;         Pointer to block to transmit
  1978.                    int count;         Size of block in bytes
  1979.  
  1980.          Examples:
  1981.  
  1982.                   ASYNC *port;
  1983.                   char buf[128];
  1984.                   static char *msg = "Send this message\r\n");
  1985.  
  1986.                   put_data_in_buf();
  1987.                   async_txblk(port, buf, sizeof(buf));
  1988.                   async_txblk(port, msg, strlen(msg));
  1989.  
  1990.          Returns: Returns the number of bytes left available in the
  1991.                   transmit ring buffer unless the ring buffer would not
  1992.                   hold the entire block when the function was called.
  1993.                   R_TXERR is returned if there was no room for the
  1994.                   block and none of the bytes in the block are sent.
  1995.  
  1996.          Remarks: This function is much faster than using repeated calls
  1997.                   to async_tx when multiple bytes are being transmitted.
  1998.                   The error return value, R_TXERR, is a negative number.
  1999.                   The bytes free return value can never be negative.
  2000.  
  2001.                   See also async_tx, async_txfree.
  2002.  
  2003.  
  2004.  
  2005.  
  2006.  
  2007.  
  2008.          async_txcnt (5.40)
  2009.          ---------------------------------------------------------------
  2010.  
  2011.          Purpose: Returns the number of bytes in the transmit ring
  2012.                   buffer.
  2013.  
  2014.          Format:  int async_txcnt(port);
  2015.                    ASYNC *port;       Pointer to ASYNC structure
  2016.  
  2017.          Example:
  2018.  
  2019.                   ASYNC *port;
  2020.  
  2021.                   BytesInTxBuf = async_txcnt(port);
  2022.  
  2023.          Returns: Number of untransmitted bytes in the transmit ring
  2024.                   buffer.
  2025.  
  2026.          Remarks: This function is implemented as a macro.  If a 16550
  2027.                   is in the system with its FIFOs active, there may be
  2028.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2029.                   the default is 3 bytes) more bytes of untransmitted
  2030.                   data in the 16550 FIFOs plus 1 byte in the UART
  2031.                   transmit hold register.  With no 16550 there may still
  2032.                   be up to 2 untransmitted bytes -- one in the UART's
  2033.                   transmit hold register and one in the UART's transmit
  2034.                   shift register.  To monitor for a transmit buffer
  2035.                   empty condition use async_txempty.
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.          async_txempty
  2043.          ---------------------------------------------------------------
  2044.  
  2045.          Purpose: Checks if transmit ring buffer is empty.
  2046.  
  2047.          Format:  int async_txempty(port);
  2048.                    ASYNC *port;       Pointer to ASYNC structure
  2049.  
  2050.          Example:
  2051.  
  2052.                   ASYNC *port;
  2053.  
  2054.                    /* wait for transmit ring buffer to empty out */
  2055.                   while (!async_txempty(port))
  2056.                       ;
  2057.  
  2058.          Returns: NZ if the transmit ring buffer is empty, ZR if the
  2059.                   buffer still has characters to be transmitted.
  2060.  
  2061.          Remarks: This function is implemented as a macro.  If a 16550
  2062.                   is in the system with its FIFOs active, there may be
  2063.                   up to 16 (depends on what async_FIFOtxlvl is set at --
  2064.                   the default is 3 bytes) more bytes of untransmitted
  2065.                   data in the 16550 FIFOs plus 1 byte in the UART
  2066.                   transmit hold register.  With no 16550 there may still
  2067.                   be up to 2 untransmitted bytes -- one in the UART's
  2068.                   transmit hold register and one in the UART's transmit
  2069.                   shift register.
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.          async_txflush
  2077.          ---------------------------------------------------------------
  2078.  
  2079.          Purpose: Flushes the transmit ring buffer.
  2080.  
  2081.          Format:  void async_txflush(port);
  2082.                    ASYNC *port;       Pointer to ASYNC structure
  2083.  
  2084.          Example:
  2085.  
  2086.                   ASYNC *port;
  2087.  
  2088.                   async_txflush(port);
  2089.  
  2090.  
  2091.          Returns: No return value
  2092.  
  2093.          Remarks: Clears the transmit ring buffer and -- if a 16550
  2094.                   operating in FIFO mode is in the system -- resets the
  2095.                   transmit FIFOs.  All characters in the buffer that
  2096.                   have not been transmitted are lost.
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.          async_txfree
  2104.          ---------------------------------------------------------------
  2105.  
  2106.          Purpose: Returns the number of bytes left available in the
  2107.                   transmit ring buffer.
  2108.  
  2109.          Format:  int async_txfree(port);
  2110.                    ASYNC *port;       Pointer to ASYNC structure
  2111.  
  2112.          Example:
  2113.  
  2114.                   ASYNC *port;
  2115.                   int tx_bytes_available;
  2116.  
  2117.                   tx_bytes_available = async_txfree(port);
  2118.  
  2119.  
  2120.          Returns: Number of bytes of free space left in the transmit
  2121.                   buffer.
  2122.  
  2123.          Remarks: The number of free bytes left in the transmit ring
  2124.                   buffer is also the return value of async_tx and
  2125.                   async_txblk.  This function is implemented as a macro.
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.          async_xany
  2133.          ---------------------------------------------------------------
  2134.  
  2135.          Purpose: Checks if accepting the first character after an XOFF
  2136.                   is received as the XON character.  DOES NOT enable any
  2137.                   character XON (use async_xflow).
  2138.  
  2139.          Format:  int async_xany(port);
  2140.                    ASYNC *port;       Pointer to ASYNC structure
  2141.  
  2142.          Example:
  2143.  
  2144.                   ASYNC *port;
  2145.                   int rcode;
  2146.  
  2147.                   rcode = async_xany(port);
  2148.  
  2149.          Returns: Not zero if first character after an XOFF is to be
  2150.                   treated as an XON.  Zero if a real XON is required to
  2151.                   clear an XOFF.
  2152.  
  2153.          Remarks: This function is implemented as a macro.  See also
  2154.                   async_xflow.
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.          async_xflow
  2162.          ---------------------------------------------------------------
  2163.  
  2164.          Purpose: Enables/disables use of XON/XOFF flow control.
  2165.  
  2166.          Format:  void async_xflow(port, flag);
  2167.                    ASYNC *port;       Pointer to ASYNC structure
  2168.                    int flag;          Enable/Disable & any char XON flag
  2169.  
  2170.          Examples:
  2171.  
  2172.                   ASYNC *port;
  2173.  
  2174.                   async_xflow(port, B_XUSE); /* use flow control */
  2175.                   async_xflow(port, 0);      /* disable flow control */
  2176.  
  2177.                    /* use XON/XOFF flow control with any char being
  2178.                       accepted as an XON */
  2179.                   async_xflow(port, B_XUSE | B_XONANY);
  2180.  
  2181.                    /* enable XON/XOFF on transmit side only */
  2182.                   async_xflow(port, B_XUSET);
  2183.  
  2184.                    /* enable XON/XOFF on receive side only */
  2185.                   async_xflow(port, B_XUSER);
  2186.  
  2187.          Returns: No return value
  2188.  
  2189.          Remarks: Passing B_XUSET enables the transmission of XON/XOFF
  2190.                   characters when the receive buffer fills to the 'trip'
  2191.                   levels discussed in the following paragraph.  Incoming
  2192.                   XON/XOFFs are not regarded as flow control characters
  2193.                   and are stored in the ring buffer.  Passing B_XUSER,
  2194.                   enables recognition of received XON/XOFFs as flow
  2195.                   characters but does not enable transmission of
  2196.                   XON/XOFF at the trip levels.  If B_XUSE is passed,
  2197.                   both transmission and recognition of XON/XOFF as flow
  2198.                   characters is enabled (the same as B_XUSET | B_XUSER).
  2199.                   ORing B_XONANY with either B_XUSE or B_XUSER causes
  2200.                   the first character received after an XOFF to be
  2201.                   treated as the XON unless that character is another
  2202.                   XOFF.  Passing zero as the flag disables XON/XOFF flow
  2203.                   control.  The default is no flow control.
  2204.  
  2205.  
  2206.  
  2207.  
  2208.  
  2209.  
  2210.          async_xflow
  2211.          ---------------------------------------------------------------
  2212.  
  2213.          Remarks (continued):
  2214.  
  2215.                   The port structure member, XoffTrip, determines when
  2216.                   an XOFF will be sent.  Whenever the number of bytes
  2217.                   left available in receive buffer falls below XoffTrip,
  2218.                   an XOFF is sent.  The default value of XoffTrip is 25%
  2219.                   of the size of the receive buffer so an XOFF is sent
  2220.                   whenever the receive buffer is 75% full.
  2221.  
  2222.                   The port structure member, XonTrip, determines when an
  2223.                   XON will be sent.  Whenever the number of bytes left
  2224.                   available in the receive buffer rises above XonTrip,
  2225.                   an XON will be sent.  Its default value is 50% of the
  2226.                   size of the receive buffer.
  2227.  
  2228.                   The port structure member, XTxRptInit, determines how
  2229.                   many bytes may be received after an XOFF is sent
  2230.                   before another XOFF is sent.  Its default value is
  2231.                   6.25% of the size of the receive buffer or 160 bytes,
  2232.                   whichever is less.
  2233.  
  2234.                   XoffTrip, XonTrip, and XTxRptInit may all be changed
  2235.                   from their default values by directly accessing the
  2236.                   port structure.  To do this:
  2237.  
  2238.                       ASYNC *port;
  2239.                      /* send XOFF when 300 bytes left in rx ring buf */
  2240.                       port->XoffTrip = 300;
  2241.                      /* send XON when 350 bytes left in rx ring buf */
  2242.                       port->XonTrip = 350;
  2243.  
  2244.                   Be sure to keep the XonTrip level higher than the
  2245.                   XoffTrip level.  The values are for bytes left
  2246.                   available not bytes used.
  2247.  
  2248.                   The XTxRptInit value is used to automatically send
  2249.                   another XOFF in the event the first one was ignored.
  2250.                   Instead of sending an XOFF character everytime another
  2251.                   character is received, the interrupt routines wait for
  2252.                   'XTxRptInit' characters to be received and then repeat
  2253.                   the XOFF.  If this value is set to low some systems
  2254.                   that allow any character to be an XON will treat the
  2255.                   repeated XOFF character as an XON.
  2256.  
  2257.  
  2258.  
  2259.  
  2260.  
  2261.  
  2262.          async_xoffclr
  2263.          ---------------------------------------------------------------
  2264.  
  2265.          Purpose: Manually clears an XOFF received condition
  2266.  
  2267.          Format:  void async_xoffclr(port);
  2268.                    ASYNC *port;       Pointer to ASYNC structure
  2269.  
  2270.          Example:
  2271.  
  2272.                   ASYNC *port;
  2273.  
  2274.                   async_xoffclr(port);
  2275.  
  2276.          Returns: No return value
  2277.  
  2278.          Remarks: Async_xoffclr has the same effect as if the remote
  2279.                   system had sent an XON.  This will unstop the system
  2280.                   in the event a false XOFF is received or the remote's
  2281.                   XON was lost.  Use this function with caution.  Unless
  2282.                   something goes wrong, the remote will clear XOFF cond-
  2283.                   itions automatically by sending an XON.  If an XOFF is
  2284.                   manually cleared, the remote site may be overran and
  2285.                   lose data.  For use only when XON/XOFF flow control
  2286.                   has been activated.
  2287.  
  2288.                   See also async_xoffset.
  2289.  
  2290.  
  2291.  
  2292.  
  2293.  
  2294.  
  2295.          async_xoffset
  2296.          ---------------------------------------------------------------
  2297.  
  2298.          Purpose: Manually sets an XOFF received condition
  2299.  
  2300.          Format:  void async_xoffset(port);
  2301.                    ASYNC *port;       Pointer to ASYNC structure
  2302.  
  2303.          Example:
  2304.  
  2305.                   ASYNC *port;
  2306.  
  2307.                   async_xoffset(port);
  2308.  
  2309.          Returns: No return value
  2310.  
  2311.          Remarks: Forces the local site to act as though an XOFF had
  2312.                   been received.  Transmit interrupts are disabled until
  2313.                   the remote sends an XON or you call async_xoffclr.
  2314.                   For use only when XON/XOFF flow control has been
  2315.                   activated.
  2316.  
  2317.                   See also async_xoffclr.
  2318.  
  2319.  
  2320.  
  2321.  
  2322.  
  2323.  
  2324.          async_xrxd
  2325.          ---------------------------------------------------------------
  2326.  
  2327.          Purpose: Check if an XOFF has been received and has activated a
  2328.                   flow control halt.
  2329.  
  2330.          Format:  int async_xrxd(port);
  2331.                    ASYNC *port;       Pointer to ASYNC structure
  2332.  
  2333.          Example:
  2334.  
  2335.                   ASYNC *port;
  2336.                   int rcode;
  2337.  
  2338.                   rcode = async_xrxd(port);
  2339.  
  2340.          Returns: Not zero if an XOFF has been received and an XON has
  2341.                   not been received to clear it.  Returns zero if XOFF
  2342.                   flow halt is not currently active.
  2343.  
  2344.          Remarks: This function is implemented as a macro.  See also
  2345.                   async_xoffclr, async_xtxd.
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.          async_xtxd
  2353.          ---------------------------------------------------------------
  2354.  
  2355.          Purpose: Check if an XOFF has been sent
  2356.  
  2357.          Format:  int async_xtxd(port);
  2358.                    ASYNC *port;       Pointer to ASYNC structure
  2359.  
  2360.          Example:
  2361.  
  2362.                   ASYNC *port;
  2363.                   int rcode;
  2364.  
  2365.                   rcode = async_xtxd(port);
  2366.  
  2367.          Returns: Not zero if an XOFF has not been sent by the receive
  2368.                   interrupt routine and an XON has not been sent to
  2369.                   clear it.  Returns zero if an XOFF has not been sent.
  2370.  
  2371.          Remarks: This function is implemented as a macro.  See also
  2372.                   async_xoffclr, async_xrxd.
  2373.  
  2374.  
  2375.  
  2376.  
  2377.  
  2378.  
  2379.          async_xuse
  2380.          ---------------------------------------------------------------
  2381.  
  2382.          Purpose: Check if XON/XOFF protocol is currently being used
  2383.  
  2384.          Format:  int async_xuse(port);
  2385.                    ASYNC *port;       Pointer to ASYNC structure
  2386.  
  2387.          Example:
  2388.  
  2389.                   ASYNC *port;
  2390.  
  2391.                   rcode = async_xuse(port);
  2392.  
  2393.          Returns: Not zero if XON/XOFF protocol is being used on either
  2394.                   the transmit or receive sides, zero if XON/XOFF flow
  2395.                   is not being used at all.
  2396.  
  2397.          Remarks: This function is implemented as a macro.  See
  2398.                   async_xflow, async_xuset, async_xuser.
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.          async_xuser
  2406.          ---------------------------------------------------------------
  2407.  
  2408.          Purpose: Check if XON/XOFF protocol is enabled on the receive
  2409.                   side (receiver recognizes XON/XOFF as flow control).
  2410.  
  2411.          Format:  int async_xuser(port);
  2412.                    ASYNC *port;       Pointer to ASYNC structure
  2413.  
  2414.          Example:
  2415.  
  2416.                   ASYNC *port;
  2417.  
  2418.                   rcode = async_xuser(port);
  2419.  
  2420.          Returns: Not zero if XON/XOFF protocol is being used on the
  2421.                   receive side, zero if it is not.
  2422.  
  2423.          Remarks: This function is implemented as a macro.  See
  2424.                   async_xflow, async_xuset, async_xuse.
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.          async_xuset
  2432.          ---------------------------------------------------------------
  2433.  
  2434.          Purpose: Check if XON/XOFF protocol is enabled on the transmit
  2435.                   side (transmitter sends XOFF/XON as receive buffer
  2436.                   bytes available crosses trip levels).
  2437.  
  2438.          Format:  int async_xuset(port);
  2439.                    ASYNC *port;       Pointer to ASYNC structure
  2440.  
  2441.          Example:
  2442.  
  2443.                   ASYNC *port;
  2444.  
  2445.                   rcode = async_xuset(port);
  2446.  
  2447.          Returns: Not zero if XON/XOFF protocol is being used on the
  2448.                   transmit side, zero if it is not.
  2449.  
  2450.          Remarks: This function is implemented as a macro.  See
  2451.                   async_xflow, async_xuser, async_xuse.
  2452.  
  2453.